﻿using System.Runtime.CompilerServices;
using RayDen.Library.Core.Primitives;

namespace RayDen.RayEngine.Engines.MCMC
{
    public class MCMCImageFilm : ImageFilm<MCMCPathTracerPath>
    {
        public MCMCImageFilm(int width, int height)
            : base(width, height)
        {
        }

        public override void Consume(PathSamplerBase pt)
        {
            var path = (MCMCPathTracerPath)pt;
            this.Samples.SplatSample(path.Sample, path.Radiance, path.pathWeight);
            // Check if the sample buffer is full
            if (this.Samples.IsFull())
            {
                this.statsTotalSampleCount += this.Samples.GetSampleCount();
                // Splat all samples on the film
                this.SplatSampleBuffer(this.IsPreviewOver(), this.Samples);
                this.Samples = this.GetFreeSampleBuffer();
            }
        }

        protected override void SplatRadiance(ref Library.Core.Primitives.RgbSpectrum radiance, int x, int y, float weight = 1.0f)
        {
            this.AddPixel(x, y, ref radiance, weight);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        protected void AddPixel(int x, int y, ref RgbSpectrum r, float w)
        {
            //var offset = x + (Height - 1 - y) * Width;
            var offset = x + (y) * this.Width;


            if (offset >= this.pixelData.Length)
                return;
            if (offset < 0)
                return;
            /*Parallel._AtomicAdd(ref pixels[offset].radiance.r, r.r);
            Parallel._AtomicAdd(ref pixels[offset].radiance.g, r.g);
            Parallel._AtomicAdd(ref pixels[offset].radiance.b, r.b);
            Parallel._AtomicAdd(ref pixels[offset].weight, w);
            */
            this.pixelData[offset].Radiance.Add(ref r);
            this.pixelData[offset].Weight += 
                w;
                //r.IsBlack() ? 0f : w;
            var i = r;
            //this.frameBuffer.SetPixel(offset, ref i);

        }
    }
}